﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using System.Data.Objects.DataClasses;
using System.Data;

namespace SmsVotes.DataAccess
{
    public static class Extensions
    {
        public static void SetAllModified<T>(this T entity, ObjectContext context)
            where T : IEntityWithKey
        {
            var stateEntry = context.ObjectStateManager.GetObjectStateEntry(entity.EntityKey);
            var propertyNameList = from item in stateEntry.CurrentValues.DataRecordInfo.FieldMetadata
                                   select item.FieldType.Name;
            foreach (var propName in propertyNameList)
                stateEntry.SetModifiedProperty(propName);
            foreach (var related in (entity as IEntityWithRelationships).RelationshipManager.GetAllRelatedEnds())
            {
            }

        }

        public static void AttachUpdated(this ObjectContext context, EntityObject objectDetached)
        {
            if (objectDetached.EntityState == EntityState.Detached)
            {
                object currentEntityInDb = null;
                if (context.TryGetObjectByKey(objectDetached.EntityKey, out currentEntityInDb))
                {
                    context.ApplyPropertyChanges(objectDetached.EntityKey.EntitySetName, objectDetached);
                    //(CDLTLL)Apply property changes to all referenced entities in context
                    context.ApplyReferencePropertyChanges((IEntityWithRelationships)objectDetached,
                                                                                        (IEntityWithRelationships)currentEntityInDb); //Custom extensor method
                }
                else
                {
                    throw new ObjectNotFoundException();
                }
            }
        }

        public static void SmartLoad<T>(this EntityCollection<T> collection, EntityObject parent) where T : EntityObject
        {
            if (!collection.IsLoaded && parent.EntityState != EntityState.Added)
                collection.Load();
        }

        public static void SmartLoad(this EntityReference reference)
        {
            if (!reference.IsLoaded)
                reference.Load();
        }

        public static void ApplyReferencePropertyChanges(this ObjectContext context, IEntityWithRelationships newEntity, IEntityWithRelationships oldEntity)
        {
            foreach (var relatedEnd in oldEntity.RelationshipManager.GetAllRelatedEnds())
            {
                var oldRef = relatedEnd as EntityReference;
                if (oldRef != null)
                {
                    // this related end is a reference not a collection
                    var newRef = newEntity.RelationshipManager.GetRelatedEnd(oldRef.RelationshipName, oldRef.TargetRoleName) as EntityReference;
                    oldRef.EntityKey = newRef.EntityKey;
                }
            }
        }
    }
}
